#ifndef OBJECT_H_
#define OBJECT_H_

#include <string>
#include <vector>
#include <btBulletDynamicsCommon.h>

#include "Prototype.h"
#include "MotionController.h"
#include "mesh/Mesh.h"
#include "math/Vector3.h"

/**
 * An Object is an instance of something that exists in the world.  Objects do
 * not draw themselves, however.  An Object is drawn based on its
 * Prototype, which can be something like a Mesh or an Armature.  Many Objects
 * can reference the same Prototype.  For example, a single tree Mesh could be
 * used as the Prototype for 100 Objects to render a forest.
 */
class Object {
protected:
	Prototype *prototype;
	Object *parent;
	std::vector<Object*> children;
	std::string name;
	btTransform transform;
	btVector3 scale;
	MotionController *motionController;

public:
	Object();
	Object(Prototype *prototype);
	void positionAt(float x, float y, float z);
	void positionAt(const Vector3 &v);
	void setRotation(float x, float y, float z);
	void setScale(float scale);

	virtual void draw();
	virtual ~Object();

	Vector3 getPosition() {
		btVector3 p = transform.getOrigin();
		return Vector3(p.x(), p.y(), p.z());
	}

    MotionController *getMotionController() const {
		return motionController;
	}

	void setMotionController(MotionController *motionController) {
		this->motionController = motionController;
	}

    std::vector<Object*> getChildren() const {
		return children;
	}

	std::string getName() const {
		return name;
	}

	Object *getParent() const {
		return parent;
	}

	Prototype *getPrototype() const {
		return prototype;
	}

	btVector3 getScale() const {
		return scale;
	}

	void setScale(const btVector3& scale) {
		this->scale = scale;
	}

	btTransform getTransform() const {
		return transform;
	}

	void setTransform(btTransform &transform) {
		this->transform = transform;
	}

	void setChildren(std::vector<Object*> children) {
		this->children = children;
	}

	void setName(std::string name) {
		this->name = name;
	}

	void setParent(Object *parent) {
		this->parent = parent;
	}

	void setPrototype(Prototype *prototype) {
		this->prototype = prototype;
	}

};

#endif /* OBJECT_H_ */
